
#include "bsp_can.h"

stc_can_rxframe_t       stcRxFrame;
stc_can_txframe_t       stcTxFrame;
uint8_t                 u8RxFlag = FALSE;

static void Can_Gpio_Init(void)
{
    stc_gpio_cfg_t stcGpioCfg;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
			
    ///< 端口驱动能力配置->高驱动能力
    stcGpioCfg.enDrv = GpioDrvH;
    ///< 端口上下拉配置->无
    stcGpioCfg.enPu = GpioPuDisable;
    stcGpioCfg.enPd = GpioPdEnable;
    ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    stcGpioCfg.enCtrlMode = GpioAHB;
    Gpio_Init(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN, &stcGpioCfg);
    ///<STB 低-PHY有效
    Gpio_ClrIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
	
	///< 端口方向配置->输入
    stcGpioCfg.enDir = GpioDirIn;
	Gpio_Init(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, &stcGpioCfg);
	 ///<CAN RX复用功能配置
    Gpio_SetAfMode(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, GpioAf1);
	
	stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, &stcGpioCfg);  
	 ///<CAN TX复用功能配置
    Gpio_SetAfMode(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, GpioAf1);

}


void BSP_Can_Init(void)
{
    stc_can_init_config_t   stcCanInitCfg;
    stc_can_filter_t        stcFilter;

	Can_Gpio_Init();
	
    Sysctrl_SetPeripheralGate(SysctrlPeripheralCan, TRUE);

    //<<CAN 波特率配置
	// 手册page884.exp: bt = (PRESC+1)((SEG_1+2) + (SEG_2+1))*(1/8M) = 1us (1000k)

#ifdef CAN_CONFIG_48MHZ_500K	 
	
	stcCanInitCfg.stcCanBt.PRESC = 6-1;
	stcCanInitCfg.stcCanBt.SEG_1 = 9-2;
	stcCanInitCfg.stcCanBt.SEG_2 = 7-1;	
	stcCanInitCfg.stcCanBt.SJW   = 3-1;	
	
//	stcCanInitCfg.stcCanBt.PRESC = 8-1;
//  stcCanInitCfg.stcCanBt.SEG_1 = 7-2;
//  stcCanInitCfg.stcCanBt.SEG_2 = 5-1;
//  stcCanInitCfg.stcCanBt.SJW   = 5-1;
	
#endif

    stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 16-1; // 10
    stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 10; // 16 -1

    stcCanInitCfg.enCanRxBufAll  = CanRxNormal;
    stcCanInitCfg.enCanRxBufMode = CanRxBufOverwritten; /*符合fifo模型*/
    stcCanInitCfg.enCanSTBMode   = CanSTBFifoMode;

    CAN_Init(&stcCanInitCfg);

    //<<CAN 滤波器配置 
	stcFilter.enAcfFormat = CanAllFrames;

#if 0  /* 设置接收白名单*/
    stcFilter.enFilterSel = CanFilterSel1;
    stcFilter.u32CODE     = 0x5c0;
    stcFilter.u32MASK     = 0x1FFFFFFF& (~0x5c0);   
    CAN_FilterConfig(&stcFilter, TRUE);
 
	stcFilter.enFilterSel = CanFilterSel2;
    stcFilter.u32CODE     = 0x445;
    stcFilter.u32MASK     = 0x1FFFFFFF& (~0x445);
	CAN_FilterConfig(&stcFilter, TRUE); 
	
	stcFilter.enFilterSel = CanFilterSel3;
    stcFilter.u32CODE     = 0x788;
    stcFilter.u32MASK     = 0x1FFFFFFF& (~0x788);
    CAN_FilterConfig(&stcFilter, TRUE);
 
	stcFilter.enFilterSel = CanFilterSel4;
	stcFilter.u32CODE     = 0x120;
	stcFilter.u32MASK     = 0x1FFFFFFF& (~0x120);
	CAN_FilterConfig(&stcFilter, TRUE);
#else

    stcFilter.enFilterSel = CanFilterSel1;
    stcFilter.u32CODE     = 0x5c0;
    stcFilter.u32MASK     = 0x1FFFFFFF;    /*u32MASK = 0x1FFFFFFF is all received*/
    CAN_FilterConfig(&stcFilter, TRUE);

#endif
    //<<Can Irq Enable
    CAN_IrqCmd(CanRxIrqEn, TRUE); /* 接收中断使能 */
	CAN_IrqCmd(CanBusErrorIrqEn, TRUE); /*总线错误中断使能*/
		
    EnableNvic(CAN_IRQn, IrqLevel0, TRUE);
}



/********************************************************************************************************
**函数信息 ：void CAN_send_Frame()
**功能描述 ：CAN发送一帧报文
**输入参数 ：stcTxFrame
**输出参数 ：None
**    备注  目前只考虑标准帧
********************************************************************************************************/
void CAN_send_Frame(stc_can_txframe_t *TxFrame, uint32_t Can_ID,uint8_t frame_len)
{
	TxFrame->StdID = Can_ID;
	TxFrame->Control_f.DLC = frame_len;
	TxFrame->Control_f.IDE = 0; /*标准帧 or 扩展帧*/
	TxFrame->Control_f.RTR = 0; /*数据帧 or 远程帧*/
	TxFrame->enBufferSel = (en_can_buffer_sel_t)0U; /*使用主缓冲器*/
	CAN_SetFrame(TxFrame); /*数据塞进fifo缓冲器*/	
	CAN_TransmitCmd(CanPTBTxCmd);
}
	
/*利用硬件fifo队列接收can数据*/
void Can_IRQHandler(void)
{
    if(TRUE == CAN_IrqFlgGet(CanRxIrqFlg))
    {
        CAN_IrqFlgClr(CanRxIrqFlg);
#ifndef CAN_USED_RECV_FIFO        
        CAN_Receive(&stcRxFrame);
        u8RxFlag = TRUE;
#endif        
    }
	 if(TRUE == CAN_IrqFlgGet(CanBusErrorIrqFlg))  /*当总线短路时,进入此中断*/
	 {	  
		  CAN_IrqFlgClr(CanBusErrorIrqFlg);	 
		// M0P_CAN->CFG_STAT = 0x00; /* 清除由硬件置位的Reset 标志位,必须在中断外部执行*/		 
	 }
}


